<?php
/**
 * Created by PhpStorm.
 * User: shaowei
 * Date: 2019/4/22
 * Time: 下午8:21
 */

namespace App\Http\Services;


use App\Http\Model\Room;
use App\Http\Model\RoomUser;
use App\Http\Model\RoomVoiceCheck;
use App\Http\Model\System;
use App\Http\Model\User;
use App\Http\Model\UserLoginLog;
use App\Lib\agora;
use App\Lib\rc;
// use App\Lib\Shumei;
use App\Http\Model\Hint;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use phpDocumentor\Reflection\DocBlock\Tags\Link;

class RoomVoiceCheckServices extends CommonServices
{
    protected $libShumei;
    protected $modelRoomVoiceCheck;
    protected $modelRoom;
    protected $libAgora;
    protected $modelUser;
    protected $modelSystem;
    protected $modelRoomUser;
    protected $system;
    protected $userLoginLog;

    public function __construct()
    {
        // $this->libShumei = new Shumei();
        $this->modelRoomVoiceCheck = new RoomVoiceCheck();
        $this->modelRoom = new Room();
        $this->libAgora = new agora();
        $this->modelUser = new User();
        $this->modelSystem = new System();
        $this->modelRoomUser = new RoomUser();
        $this->system = new System();
        $this->userLoginLog = new UserLoginLog();
    }

    public function addTask($roomId, $time, $isMixingEnabled = true)
    {
        $task = $this->modelRoomVoiceCheck->getTask($roomId);
        // 房间任务已经存在
        if (!empty($task)) {
            return;
        }
        //等待期（每5分钟检测3分钟，其他时间为等待期）
        $wait_time = $this->modelRoomVoiceCheck->getTaskWaitTime($roomId);
        if(!empty($wait_time)){
            return;
        }
        $callBackUrl = env('APP_URL') . '/room/voice/check/callback';
        $uid = 9000000 + $roomId;
        if($this->modelRoom->getAig($roomId)) {
            $this->libAgora->aig();
        }

        list($interval, $checkTime, $mixingEnabled) = $this->getCheckTime($roomId);
        $checkTime = time() + $checkTime;

        $agoraToken = $this->libAgora->getToken($roomId, $uid);
        $taskId = $this->libShumei->addTask($roomId, $agoraToken, $uid, $callBackUrl, $mixingEnabled);
        if (empty($taskId)) {
            return;
        }
        $this->modelRoomVoiceCheck->addTask($roomId, $taskId, $interval, $checkTime);
    }

    /**
     * 高频分流检测
     */
    public function loopHighShuntStart()
    {
        $openRoomArr = $this->modelRoom->getOpenedRoomIdArr();
        //$openRoomArr = $this->modelRoomVoiceCheck->getLoopShuntRoomIdArr();
        foreach ($openRoomArr as $roomId) {
            $userCount = $this->modelRoomUser->get_users_count($roomId);
            $openRes = $this->modelRoom->get_opened($roomId);
            //判断房间是否开启与房间内人数
            if ($userCount < 1 || !$openRes) {
                continue;
            }
//            if (!$this->modelRoomVoiceCheck->isHighRoom($roomId)){
//                continue;
//            }

//            $res = $this->checkVoice($roomId);
//            if(!$res) {
//                continue;
//            }

            //不禁用分流
            // $this->addTask($roomId, 4*60, false);
        }
    }

    /**
     * 高频检测
     */
    public function loopHighStart(){
        $openRoomArr = $this->modelRoom->getOpenedRoomIdArr();
        foreach ($openRoomArr as $roomId) {
            $userCount = $this->modelRoomUser->get_users_count($roomId);
            if ($userCount < 1) {
                continue;
            }
            if (!$this->modelRoomVoiceCheck->isHighRoom($roomId)){
                continue;
            }
//            $res = $this->checkVoice($roomId);
//            if(!$res) {
//                continue;
//            }

            //$this->addTask($roomId, 4*60);
        }
    }

    public function loopStart()
    {
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [];
        do {
            $opened = $this->modelRoomVoiceCheck->getState();
            if ($opened == 0) {
                break;
            }
            $this->loopHighShuntStart();   //高频分流检测
//            $this->loopHighStart();        //高频检测
//            $intervalTime = $this->modelRoomVoiceCheck->getConfigIntervalTime();
//            $now = time();
//            if ($intervalTime > 0) {
//                $lastTime = $this->modelRoomVoiceCheck->getConfigLast();
//                if ($now - $lastTime < $intervalTime) {
//                    break;
//                }
//            }
//            $openRoomArr = $this->modelRoom->getOpenedRoomIdArr();
//            $duration = $this->modelRoomVoiceCheck->getConfigDuration();
//            $this->modelRoomVoiceCheck->setConfigLast($now);
//            foreach ($openRoomArr as $roomId) {
//                $userCount = $this->modelRoomUser->get_users_count($roomId);
//                if ($userCount < 1) {
//                    continue;
//                }
//                $this->addTask($roomId, $duration);
//            }
        } while (false);
        return compact('code', 'msg', 'data');
    }

    public function loopStop()
    {
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [];
        do {
            $opened = $this->modelRoomVoiceCheck->getState();

            /**
             * 清理不在线的房间
             */
            $tasks = $this->modelRoomVoiceCheck->getTaskAll();
            foreach ($tasks as $k => $v) {
                if ($this->modelRoomUser->get_users_count($k) > 0) {
                    continue;
                }
                write_log('sumei', 'deltask', ["不在线房间删除任务",$v[0],$k]);
                $taskId = $this->libShumei->delTask($v[0]);
                $this->modelRoomVoiceCheck->delTask($k);
            }

            /**
             * 不间断检测
             */
            if ($opened == 2) {
                break;
            }
            $nowTime = time();
            $mapTask = [];
            $tasks = $this->modelRoomVoiceCheck->getTaskAll();
            foreach ($tasks as $k => $v) {
                if ($v[1] > $nowTime and $opened > 0) {
                    $mapTask[$v[0]] = $k;
                    continue;
                }
                write_log('sumei', 'deltask', ["检测时间到了删除任务",$v[0],$k]);
                $taskId = $this->libShumei->delTask($v[0]);
                if (empty($taskId)) {
                    continue;
                }
                $this->modelRoomVoiceCheck->delTask($k);
            }
            $sumeiTasks = $this->libShumei->queryTask();
            foreach ($sumeiTasks as $task) { //add by zixiaofee 修改redis任务列表没有的问题
                if (time()-4*60 > strtotime($task['audioStarttime'])) {
                    write_log('sumei', 'deltask', ["没在任务列表的删除任务"]);
                    $this->libShumei->delTask($task['requestId']);
                }
//                if (!array_key_exists($task['requestId'], $mapTask)) {
//                    write_log('sumei', 'deltask', ["没在任务列表的删除任务",$task['requestId'],$mapTask]);
//                    $this->libShumei->delTask($task['requestId']);
//                }
            }
        } while (false);


        return compact('code', 'msg', 'data');
    }


    public function callBack()
    {
        write_log('sumei', 'callback', $this->requestData);
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [];
        // 解决Code变量冲突问题
        if (isset($this->requestData['code'])) {
            $this->requestData['err_code'] = $this->requestData['code'];
            unset($this->requestData['code']);
        }

        // 1100 成功
        if ($this->requestData['err_code'] == 1100) {
            //违规内容直接拦截
            if ($this->requestData['riskLevel'] == 'REJECT') {
                if ($riskType = $this->requestData['detail']['riskType']) {

                    $room_uid = $this->requestData['detail']['room'];
                    $user_uid = $this->requestData['detail']['userId'] ?? 0;
                    $type_name = $this->requestData['detail']['riskTypeDesc'] ?? "";

                    //判断房间是否为高频分流房间
                    //坑爹逻辑，这个if必然会进入。下面的else没用，可能被废弃了。
                    if (true || $this->modelRoomVoiceCheck->isHighShuntRoom($room_uid)) {
                        $roomInfo = $this->modelRoom->get_room($room_uid);
                        $userInfo = $this->modelUser->get_user($user_uid);
                        write_log('sumei', 'highShuntCheck', $this->requestData);
                        if ($user_uid > 0) {
                            //色情，娇喘直接封号
                        //    $riskTypeArr = [200, 250];
                            //娇喘直接封号
                            $riskTypeArr = [250];
                            if (in_array($riskType, $riskTypeArr)) {

                                //读取涉黄验证开关
                                $config = $this->system->get_config();
                                $switch = intval($config['pron_switch']['value'] ?? 0); //0不开启;1小屋;2CBD;3小屋+CBD
                                $businessType = intval($roomInfo['business_type'] ?? 0); //0小屋;1CBD

                                $blockMicro = false; //是否禁麦
                                if($switch == 0){ //如果开关关闭
                                    $blockMicro = false; //不禁麦，直接封号
                                }else{
                                    if ($businessType == 0 && ($switch == 1 || $switch == 3)) { //小屋
                                        $blockMicro = true;
                                    } elseif ($businessType == 1 && ($switch == 2 || $switch == 3)) { //CBD
                                        $blockMicro = true;
                                    }
                                }

                                //检查禁麦次数
                                $blockNum = $this->modelUser->countMicroBlock($user_uid);

                                if ($blockMicro == true && empty($blockNum) ) {
                                    //首次禁麦10分钟
                                    $info = $this->requestData['detail']['audioUrl'];
                                    $this->modelUser->userMicroBlock($user_uid, $info, 1, 10);
                                    $data['type'] = 2; //警告
                                } else {
                                    //多次封号24小时
                                    $requestData = [
                                        'user_id' => $userInfo['user_id'],
                                        'operate_info' => $this->requestData['detail']['audioUrl'],
                                        'uuid' => $userInfo['user_uid']
                                    ];
                                    $this->userForbid($requestData);
                                    $data['type'] = 1; //封号
                                }


                                //回调
                                $data['room_id'] = $roomInfo['room_id'];
                                $data['user_id'] = $userInfo['user_id'];
                                $data['type_name'] = $type_name;
                                $data['risk_type'] = $riskType;
                            }
                        }
                    }else {
                        // 获取房间详情
                        $roomInfo = $this->modelRoom->get_room($room_uid);
                        // 密码房间直接退出
                        // $password = $this->modelRoom->get_password($room_uid);
                        // if (!empty($password) && $roomInfo['business_type'] == 0){
                        //    return compact('code', 'msg', 'data');
                        // }

                        if ($user_uid > 0) {
                            // 获取用户详情
                            $userInfo = $this->modelUser->get_user($user_uid);
                            // 通知
                            if (!$this->modelRoomVoiceCheck->checkIsHandle($userInfo['user_id'], $riskType)) {
                                if (!empty($checkItems) && $userInfo && $roomInfo) {
                                    foreach ($checkItems as $checkItem) {
                                        if ($checkItem['audit'] == $riskType) {
                                            $data['room_id'] = $roomInfo['room_id'];
                                            $data['user_id'] = $userInfo['user_id'];
                                            $data['type_name'] = $type_name;
                                            $data['risk_type'] = $riskType;
                                            switch ($checkItem['handle']) {
                                                case 1: // 封号
                                                    $data['type'] = 1;
                                                    break;
                                                case 2: // 警告
                                                    $data['type'] = 2;
                                                    break;
                                                case 3: // 通知客服
                                                    $data['type'] = 3;
                                                    break;
                                                case 4: // 封号+通知客服
                                                    $data['type'] = 4;
                                                    break;
                                                case 5: // 警告+通知客服
                                                    $data['type'] = 5;
                                            }
                                            break;
                                        }
                                    }
                                }

                                $this->modelRoomVoiceCheck->setHandleUser($userInfo['user_id'], $riskType);
                            }
                        }
                    }

                    // 记录日志
                    $this->modelRoom->createVoiceCheckLog([
                        'user_id' => $user_uid,
                        'room_id' => $roomInfo['room_id'],
                        'illegal_desc' => $type_name,
                        'illegal_mp3' => $this->requestData['detail']['audioUrl'],
                        'illegal_times' => time(),
                    ]);
                }
            }
        }
        return compact('code', 'msg', 'data');
    }

    public function setConfig()
    {
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [];

        $this->modelRoomVoiceCheck->setConfigIntervalTime($this->requestData['intervalTime']);
        $this->modelRoomVoiceCheck->setConfigDuration($this->requestData['duration']);
        $this->modelRoomVoiceCheck->setConfigCheckItems($this->requestData['checkItems']);
        $this->modelRoomVoiceCheck->setState($this->requestData['state']);

        return compact('code', 'msg', 'data');
    }

    public function getConfig()
    {
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [
            'interval_time' => $this->modelRoomVoiceCheck->getConfigIntervalTime(),
            'duration' => $this->modelRoomVoiceCheck->getConfigDuration(),
            'state' => $this->modelRoomVoiceCheck->getState(),
        ];
        return compact('code', 'msg', 'data');
    }

    /*
     * 修改语音审查记录状态
     * */
    public function updateVoiceCheckLog($id,$status)
    {
        return $this->modelRoom->updateVoiceCheckLogStatus($id,$status);
    }

    /**
     * 记录封号操作
     * @param $requestData
     */
    public function userForbid($requestData)
    {
        $requestData['operation_id'] = 18;
        $requestData['reason_id'] = 43;
        $requestData['forbid_type'] = 1;
        $requestData['operate_type'] = 1;
        $requestData['block_time'] = time() + 43200 * 2;  //封号时长


        $insertId = $this->modelUser->userForbid($requestData);
        if(!$insertId) {
            write_log('sumeiUserForbid', 'forbidError:', $insertId);
        }else {
            write_log('sumeiUserForbid', 'forbidSuccess:', $insertId);
        }
    }

    /**
     * 获取所有高频检测房间
     * @return mixed
     */
    public function getHighRooms(){
        return $this->modelRoomVoiceCheck->getHighRooms();
    }


    /**
     * 添加高频检测房间
     * @return mixed
     */
    public function addHighRoom($roomId){
        return $this->modelRoomVoiceCheck->addHighRoom($roomId);
    }

    /**
     * 删除高频检测房间
     * @return mixed
     */
    public function delHighRoom($roomId){
        return $this->modelRoomVoiceCheck->delHighRoom($roomId);
    }

    /**
     * 查询房间是否属于高频分流检测
     * @param $roomId
     */
    public function isHighShuntRoom($roomId)
    {
        return $this->modelRoomVoiceCheck->isHighShuntRoom($roomId);
    }

    /**
     * todo 判断是否为小屋，用于关闭检测任务
     */
    public function checkVoice($roomId)
    {
        //todo 判断是否为小屋，用于关闭检测任务
        $businessType = $this->modelRoom->get_room_business_type($roomId);
        $password = $this->modelRoom->get_password($roomId);

        //小屋并且锁房状态下关闭检测
        if($businessType == 0 && $password !== null) {
            $task = $this->modelRoomVoiceCheck->getTask($roomId);
            // 房间任务已经存在
            if (!empty($task)) {
                $this->libShumei->delTask($task[0]);
                //关闭检测任务
                $this->modelRoomVoiceCheck->delTask($roomId);
                return false;
            }
        }

        return true;
    }

    public function getCheckTime($roomId) : array {
        $roomType = (new Room())->getRoomTypeByRoomId($roomId);
        $isMixingEnabled = false;
        if ($roomType['business_type'] == 0) {
            $isMixingEnabled = true;
        }
        $isMixingEnabled = false;//都分流
        if (in_array($roomType['room_type'], [40])) {
            return [5 * 60, 4 * 60, $isMixingEnabled];
        }
        if (in_array($roomType['room_type'], [39])) {
            return [5 * 60, 3 * 60, $isMixingEnabled];
        }
        return [5 * 60, 3 * 60, $isMixingEnabled];
    }

    /**
     * 消息回调服务
     *
     * @return array
     */
    public function messageCallback($request)
    {
        write_log('sumei', 'messageCallback', ["request" => $request]);
        /*$msgType = $request['msgType'];
        $appKey = $request['appKey'];
        $messageId = $request['messageId'];
        $msgTimeStamp = $request['msgTimeStamp'];
        $channelType = $request['channelType'];
        $os = $request['os'];
        $busChannel = $request['busChannel'];*/
        
        //记录萌新聊天记录
        $content = json_decode($request['content'],1);
        $fromUserId = $request['fromUserId'];
        $targetId = $request['targetId'];

        (new MsgServices())->novicePrivateMsg($fromUserId,$targetId,$content['content']);

        return ['pass' => 1];

    }

}
